"""
定时任务相关的Pydantic模式
"""
from pydantic import BaseModel, Field, validator
from typing import Optional, Dict, Any, List
from datetime import datetime
from uuid import UUID
from enum import Enum


class JobStatus(str, Enum):
    """任务状态枚举"""
    ACTIVE = "active"
    INACTIVE = "inactive"
    RUNNING = "running"
    PAUSED = "paused"


class JobType(str, Enum):
    """任务类型枚举"""
    CRON = "cron"
    INTERVAL = "interval"
    DATE = "date"


class TriggerType(str, Enum):
    """触发器类型枚举"""
    MANUAL = "manual"
    AUTO = "auto"
    API = "api"


class ExecutionStatus(str, Enum):
    """执行状态枚举"""
    SUCCESS = "SUCCESS"
    FAILED = "FAILED"
    TIMEOUT = "TIMEOUT"
    RUNNING = "RUNNING"
    PENDING = "PENDING"


# ==================== 任务相关模式 ====================

class JobBase(BaseModel):
    """任务基础模式"""
    job_name: str = Field(..., min_length=1, max_length=100, description="任务名称")
    job_group: str = Field(default="DEFAULT", max_length=50, description="任务分组")
    description: Optional[str] = Field(None, description="任务描述")
    job_type: JobType = Field(default=JobType.CRON, description="任务类型")
    executor_handler: str = Field(..., min_length=1, max_length=200, description="执行器处理器")
    executor_params: Optional[Dict[str, Any]] = Field(None, description="执行器参数")
    author: Optional[str] = Field(None, max_length=100, description="负责人")
    alarm_email: Optional[str] = Field(None, max_length=500, description="报警邮件")


class JobCreate(JobBase):
    """创建任务模式"""
    cron_expression: Optional[str] = Field(None, max_length=100, description="CRON表达式")
    interval_seconds: Optional[int] = Field(None, ge=1, description="间隔秒数")
    start_time: Optional[datetime] = Field(None, description="开始时间")
    end_time: Optional[datetime] = Field(None, description="结束时间")
    timeout_seconds: int = Field(default=0, ge=0, description="超时时间(秒)")
    retry_count: int = Field(default=0, ge=0, le=10, description="重试次数")
    retry_interval: int = Field(default=30, ge=1, description="重试间隔(秒)")
    route_strategy: str = Field(default="FIRST", description="路由策略")
    executor_block_strategy: str = Field(default="SERIAL_EXECUTION", description="阻塞处理策略")

    @validator('cron_expression')
    def validate_cron_expression(cls, v, values):
        """验证CRON表达式"""
        if values.get('job_type') == JobType.CRON and not v:
            raise ValueError('CRON类型任务必须提供CRON表达式')
        if v:
            # 简单的CRON表达式验证
            try:
                from croniter import croniter
                croniter(v)
            except Exception:
                raise ValueError('CRON表达式格式不正确')
        return v

    @validator('interval_seconds')
    def validate_interval_seconds(cls, v, values):
        """验证间隔秒数"""
        if values.get('job_type') == JobType.INTERVAL and not v:
            raise ValueError('间隔类型任务必须提供间隔秒数')
        return v

    @validator('start_time')
    def validate_start_time(cls, v, values):
        """验证开始时间"""
        if values.get('job_type') == JobType.DATE and not v:
            raise ValueError('定时类型任务必须提供开始时间')
        return v


class JobUpdate(BaseModel):
    """更新任务模式"""
    job_name: Optional[str] = Field(None, min_length=1, max_length=100, description="任务名称")
    job_group: Optional[str] = Field(None, max_length=50, description="任务分组")
    description: Optional[str] = Field(None, description="任务描述")
    job_type: Optional[JobType] = Field(None, description="任务类型")
    executor_handler: Optional[str] = Field(None, min_length=1, max_length=200, description="执行器处理器")
    executor_params: Optional[Dict[str, Any]] = Field(None, description="执行器参数")
    cron_expression: Optional[str] = Field(None, max_length=100, description="CRON表达式")
    interval_seconds: Optional[int] = Field(None, ge=1, description="间隔秒数")
    start_time: Optional[datetime] = Field(None, description="开始时间")
    end_time: Optional[datetime] = Field(None, description="结束时间")
    timeout_seconds: Optional[int] = Field(None, ge=0, description="超时时间(秒)")
    retry_count: Optional[int] = Field(None, ge=0, le=10, description="重试次数")
    retry_interval: Optional[int] = Field(None, ge=1, description="重试间隔(秒)")
    route_strategy: Optional[str] = Field(None, description="路由策略")
    executor_block_strategy: Optional[str] = Field(None, description="阻塞处理策略")
    author: Optional[str] = Field(None, max_length=100, description="负责人")
    alarm_email: Optional[str] = Field(None, max_length=500, description="报警邮件")


class JobResponse(JobBase):
    """任务响应模式"""
    id: UUID
    job_status: JobStatus
    cron_expression: Optional[str] = None
    interval_seconds: Optional[int] = None
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    timeout_seconds: int
    retry_count: int
    retry_interval: int
    route_strategy: str
    executor_block_strategy: str
    is_active: bool
    created_at: datetime
    updated_at: Optional[datetime] = None
    created_by: Optional[UUID] = None
    updated_by: Optional[UUID] = None

    class Config:
        from_attributes = True


class JobListResponse(BaseModel):
    """任务列表响应模式"""
    items: List[JobResponse]
    total: int
    page: int
    per_page: int
    pages: int


# ==================== 任务操作相关模式 ====================

class JobTrigger(BaseModel):
    """手动触发任务模式"""
    executor_params: Optional[Dict[str, Any]] = Field(None, description="执行器参数")
    trigger_type: TriggerType = Field(default=TriggerType.MANUAL, description="触发类型")


class JobStatusUpdate(BaseModel):
    """任务状态更新模式"""
    job_status: JobStatus = Field(..., description="任务状态")


# ==================== 任务日志相关模式 ====================

class JobLogBase(BaseModel):
    """任务日志基础模式"""
    trigger_type: TriggerType = Field(default=TriggerType.AUTO, description="触发类型")
    executor_handler: str = Field(..., description="执行器处理器")
    executor_params: Optional[Dict[str, Any]] = Field(None, description="执行器参数")


class JobLogCreate(JobLogBase):
    """创建任务日志模式"""
    job_id: UUID = Field(..., description="任务ID")
    trigger_time: datetime = Field(default_factory=datetime.now, description="触发时间")


class JobLogUpdate(BaseModel):
    """更新任务日志模式"""
    start_time: Optional[datetime] = Field(None, description="开始执行时间")
    end_time: Optional[datetime] = Field(None, description="结束执行时间")
    status: Optional[ExecutionStatus] = Field(None, description="执行状态")
    result_code: Optional[int] = Field(None, description="执行结果码")
    result_msg: Optional[str] = Field(None, description="执行结果信息")
    executor_address: Optional[str] = Field(None, description="执行器地址")
    executor_sharding_param: Optional[str] = Field(None, description="分片参数")
    executor_fail_retry_count: Optional[int] = Field(None, description="失败重试次数")
    process_log: Optional[str] = Field(None, description="执行过程日志")
    error_log: Optional[str] = Field(None, description="错误日志")


class JobLogResponse(JobLogBase):
    """任务日志响应模式"""
    id: UUID
    job_id: UUID
    trigger_time: datetime
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    status: Optional[ExecutionStatus] = None
    result_code: Optional[int] = None
    result_msg: Optional[str] = None
    executor_address: Optional[str] = None
    executor_sharding_param: Optional[str] = None
    executor_fail_retry_count: Optional[int] = None
    process_log: Optional[str] = None
    error_log: Optional[str] = None

    class Config:
        from_attributes = True


class JobLogListResponse(BaseModel):
    """任务日志列表响应模式"""
    items: List[JobLogResponse]
    total: int
    page: int
    per_page: int
    pages: int


# ==================== 任务分组相关模式 ====================

class JobGroupBase(BaseModel):
    """任务分组基础模式"""
    group_name: str = Field(..., min_length=1, max_length=50, description="分组名称")
    title: str = Field(..., min_length=1, max_length=100, description="分组标题")
    description: Optional[str] = Field(None, description="分组描述")
    address_type: int = Field(default=0, description="注册方式: 0=自动注册, 1=手动录入")
    address_list: Optional[str] = Field(None, description="机器地址列表")


class JobGroupCreate(JobGroupBase):
    """创建任务分组模式"""
    pass


class JobGroupUpdate(BaseModel):
    """更新任务分组模式"""
    group_name: Optional[str] = Field(None, min_length=1, max_length=50, description="分组名称")
    title: Optional[str] = Field(None, min_length=1, max_length=100, description="分组标题")
    description: Optional[str] = Field(None, description="分组描述")
    address_type: Optional[int] = Field(None, description="注册方式")
    address_list: Optional[str] = Field(None, description="机器地址列表")


class JobGroupResponse(JobGroupBase):
    """任务分组响应模式"""
    id: UUID
    is_active: bool
    created_at: datetime
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


# ==================== 统计相关模式 ====================

class JobStatistics(BaseModel):
    """任务统计模式"""
    total_jobs: int = Field(..., description="总任务数")
    active_jobs: int = Field(..., description="活跃任务数")
    running_jobs: int = Field(..., description="运行中任务数")
    failed_jobs_today: int = Field(..., description="今日失败任务数")
    success_jobs_today: int = Field(..., description="今日成功任务数")
    total_executions_today: int = Field(..., description="今日总执行次数")


class JobExecutionTrend(BaseModel):
    """任务执行趋势模式"""
    date: str = Field(..., description="日期")
    success_count: int = Field(..., description="成功次数")
    failed_count: int = Field(..., description="失败次数")
    total_count: int = Field(..., description="总次数")